/* DOES NOT USE BUILT-IN DETECTION FUNCTION!

alert tcp $EXTERNAL_NET any -> $HOME_NET 389 (msg:"DOS Active Directory malformed baseObject denial of service attempt"; flow:to_server,established; content:"|30|"; depth:1; metadata:service ldap, policy security-ips drop, policy balanced-ips drop; reference:cve,2008-4023; reference:url,technet.microsoft.com/en-us/security/bulletin/MS08-060; classtype:attempted-dos; sid:14646; rev:1;)
*/
/*
 * Use at your own risk.
 *
 * Copyright (C) 2005-2008 Sourcefire, Inc.
 * 
 * This file is autogenerated via rules2c, by Brian Caswell <bmc@sourcefire.com>
 */


#include "sf_snort_plugin_api.h"
#include "sf_snort_packet.h"

#include "so-util_ber.h"

//#define DEBUG
#ifdef DEBUG
#define DEBUG_WRAP(code) code
#else
#define DEBUG_WRAP(code)
#endif

/* declare detection functions */
int rule14646eval(void *p);

/* declare rule data structures */
/* precompile the stuff that needs pre-compiled */
/* flow:established, to_server; */
static FlowFlags rule14646flow0 = 
{
    FLOW_ESTABLISHED|FLOW_TO_SERVER
};

static RuleOption rule14646option0 =
{
    OPTION_TYPE_FLOWFLAGS,
    {
        &rule14646flow0
    }
};
// content:"0", depth 1; 
static ContentInfo rule14646content1 = 
{
    (uint8_t *) "0", /* pattern (now in snort content format) */
    1, /* depth */
    0, /* offset */
    CONTENT_BUF_NORMALIZED, /* flags */ // XXX - need to add CONTENT_FAST_PATTERN support
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule14646option1 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule14646content1
    }
};

/* references for sid 14646 */
/* reference: cve "2008-4023"; */
static RuleReference rule14646ref1 = 
{
    "cve", /* type */
    "2008-4023" /* value */
};

/* reference: url "technet.microsoft.com/en-us/security/bulletin/MS08-060"; */
static RuleReference rule14646ref2 = 
{
    "url", /* type */
    "technet.microsoft.com/en-us/security/bulletin/MS08-060" /* value */
};

static RuleReference *rule14646refs[] =
{
    &rule14646ref1,
    &rule14646ref2,
    NULL
};

/* metadata for sid 14646 */
/* metadata:service ldap, policy balanced-ips drop, policy security-ips drop; */
//static RuleMetaData rule14646service1 = 
//{
//    "service ldap"
//};
//
//
static RuleMetaData rule14646policy1 = 
{
    "policy max-detect-ips drop"
};
//
//static RuleMetaData rule14646policy2 = 
//{
//    "policy security-ips drop"
//};


static RuleMetaData *rule14646metadata[] =
{
//    &rule14646service1,
    &rule14646policy1,
//    &rule14646policy2,
    NULL
};

RuleOption *rule14646options[] =
{
    &rule14646option0,
    &rule14646option1,
    NULL
};

Rule rule14646 = {
   
   /* rule header, akin to => tcp any any -> any any               */{
       IPPROTO_TCP, /* proto */
       "$EXTERNAL_NET", /* SRCIP     */
       "any", /* SRCPORT   */
       0, /* DIRECTION */
       "$HOME_NET", /* DSTIP     */
       "389", /* DSTPORT   */
   },
   /* metadata */
   { 
       3,  /* genid (HARDCODED!!!) */
       14646, /* sigid */
       8, /* revision */
   
       "attempted-dos", /* classification */
       0,  /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */
       "OS-WINDOWS Active Directory malformed baseObject denial of service attempt",     /* message */
       rule14646refs /* ptr to references */
       ,rule14646metadata
   },
   rule14646options, /* ptr to rule options */
   &rule14646eval, /* DO *NOT* use the built in detection function */
   0 /* am I initialized yet? */
};


/* detection functions */
int rule14646eval(void *p) {
   const uint8_t *cursor_normal = 0, *end_of_payload;
   SFSnortPacket *sp = (SFSnortPacket *) p;

   int retval;
   BER_ELEMENT element;

   if(sp == NULL)
      return RULE_NOMATCH;

   if(sp->payload == NULL)
      return RULE_NOMATCH;
   
   // flow:established, to_server;
   if(checkFlow(p, rule14646options[0]->option_u.flowFlags) <= 0 )
      return RULE_NOMATCH;
 
   if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &cursor_normal, &end_of_payload) <= 0)
      return RULE_NOMATCH;

   // Universal Sequence
   if(ber_point_to_data(sp, &cursor_normal, 0x30) < 0)
      return RULE_NOMATCH;

   // message ID
   if(ber_skip_element(sp, &cursor_normal, 0x02) < 0)
      return RULE_NOMATCH;

   // search request
   if(ber_point_to_data(sp, &cursor_normal, 0x63) < 0)
      return RULE_NOMATCH;

   // Here's the meat
   retval = ber_get_element(sp, cursor_normal, &element);

   if(retval == -1)
      return RULE_NOMATCH;

   //DEBUG_WRAP(printf("found baseObject string.  checking values type=0x%02x size=%d\n", element.type, element.data_len));

   /* vuln is 0x43 + len(baseObject first part) + 3 * len(baseObject dc) > 0xFFA
      We simplify to data_len > 1200 since that's more than reasonable and shortest possible
      length to exploit is len(baseObject) == len(d) == 1363
   */
   if(element.type == 0x04 && ((element.data_len > 1200) || (retval == -2)))
      return RULE_MATCH;

   return RULE_NOMATCH;
}

/*
Rule *rules[] = {
    &rule14646,
    NULL
};
*/

